import { ref, onUnmounted, watch, unref, toRaw } from 'vue';
import type { WatchStopHandle } from 'vue';
import type { PaginationProps } from '@/components/Table/src/types/pagination';

import type { DynamicProps } from '#/utils';
import type { FormActionType } from '@/components/Form';

import { FormModeEnum } from '@/enums/formEnum';

import { isProdMode } from '@/utils/env';
import { getDynamicProps } from '@/utils';
import { error } from '@/utils/log';

import type { AdListProps, AdListActionType } from '../types/adList';
import type { AdFetchParams } from '@/components/AdTable';

type Props = Partial<DynamicProps<AdListProps>>;

type UseListMethod = AdListActionType & {
  getForm: () => FormActionType;
};

/**
 * 使用高级列表
 * @param tableProps 列表选项
 * @returns 高级列表对象
 */
export function useAdList(listProps?: Props): [
  (instance: AdListActionType, formInstance: UseListMethod) => void,
  AdListActionType & {
    getForm: () => FormActionType;
  },
] {
  const tableRef = ref<Nullable<AdListActionType>>(null);
  const loadedRef = ref<Nullable<boolean>>(false);
  const formRef = ref<Nullable<UseListMethod>>(null);

  let stopWatch: WatchStopHandle;

  /** 注册 */
  function register(instance: AdListActionType, formInstance: UseListMethod) {
    isProdMode() &&
      onUnmounted(() => {
        tableRef.value = null;
        loadedRef.value = null;
      });

    if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) return;

    tableRef.value = instance;
    formRef.value = formInstance;
    listProps && instance.setProps(getDynamicProps(listProps));
    loadedRef.value = true;

    stopWatch?.();

    stopWatch = watch(
      () => listProps,
      () => {
        listProps && instance.setProps(getDynamicProps(listProps));
      },
      {
        immediate: true,
        deep: true,
      },
    );
  }

  /** 获取高级列表实例 */
  function getListInstance(): AdListActionType {
    const list = unref(tableRef);
    if (!list) {
      error('尚未获取列表实例，请在执行表操作时确保表已呈现！');
    }
    return list as AdListActionType;
  }

  const methods: AdListActionType & {
    getForm: () => FormActionType;
  } = {
    /** 重新加载 */
    reload: async (opt?: AdFetchParams) => {
      return getListInstance().reload(opt);
    },
    /** 滚动至 */
    scrollTo: (pos: number | 'top' | 'bottom') => {
      getListInstance().scrollTo(pos);
    },
    /** 获取分页 */
    getPagination: () => {
      return getListInstance().getPagination();
    },
    /** 设置分页 */
    setPagination: (info: Partial<PaginationProps>) => {
      return getListInstance().setPagination(info);
    },
    /** 获取分页是否显示 */
    getShowPagination: () => {
      return getListInstance().getShowPagination();
    },
    /** 设置分页是否显示 */
    setShowPagination: async (show: boolean) => {
      await getListInstance().setShowPagination(show);
    },
    /** 获取原始数据 */
    getRawDataSource: () => {
      return getListInstance().getRawDataSource();
    },
    /** 获取搜索信息 */
    getSearchInfo: () => {
      return getListInstance().getSearchInfo();
    },
    /** 获取列表数据 */
    getListData: () => {
      return getListInstance().getListData();
    },
    /** 设置列表数据 */
    setListData: (values: any[]) => {
      getListInstance().setListData(values);
    },
    /** 更新列表指定数据 */
    updateListData: (index: number, key: string, value: any) => {
      return getListInstance().updateListData(index, key, value);
    },
    /** 更新列表指定记录 */
    updateListDataRecord: (rowKey: string | number, record: Recordable) => {
      return getListInstance().updateListDataRecord(rowKey, record);
    },
    /** 删除列表指定记录 */
    deleteListDataRecord: (rowKey: string | number | string[] | number[]) => {
      getListInstance().deleteListDataRecord(rowKey);
    },
    /** 插入列表指定记录 */
    insertListDataRecord: (record: Recordable | Recordable[], index?: number) => {
      return getListInstance().insertListDataRecord(record, index);
    },
    /** 查找列表指定记录 */
    findListDataRecord: (rowKey: string | number) => {
      return getListInstance().findListDataRecord(rowKey);
    },
    /** 设置加载状态 */
    setLoading: (loading: boolean) => {
      getListInstance().setLoading(loading);
    },
    /** 设置参数 */
    setProps: (props: Partial<AdListProps>) => {
      getListInstance().setProps(props);
    },
    /** 重新构建高度 */
    redoHeight: () => {
      getListInstance().redoHeight();
    },
    /** 获取尺寸 */
    getSize: () => {
      return toRaw(getListInstance().getSize());
    },
    /** 打开详情表单 */
    openDetailForm: (formMode: FormModeEnum, record?: Recordable<any>) => {
      getListInstance().openDetailForm(formMode, record);
    },
    getForm: () => {
      return unref(formRef) as unknown as FormActionType;
    },
  };

  return [register, methods];
}
